package modelo.controlAereo;

import modelo.Escenografia.*;
import modelo.Orientacion.*;
import java.util.ArrayList;
import java.util.Iterator;

/*La idea de esta clase es que se encargue de la creacion aleatoria de las aeronaves dentro del escenario*/
public class IndustriaDeAeronaves {

    private Posicion posicion;
    private Direccion direccion;

    public void IndustriaDeAeronaves(){
    }

    public Aeronave crearUnaAeronave(Escenario escenario, int velocidad){
    /*PreCondicion: la industria debe haberse creado, el escenario debe contener al menos una pista
      PostCondicion: devuelve una aeronave que pueda aterrizar en el escenario*/
        Aeronave aeronave = null;
        this.crearUnaPosicionAleatoriaYDireccion(escenario.devolverExtremoDerecho()-1, escenario.devolverExtremoSuperior()-1);
        while(aeronave == null) aeronave = this.crearAeronave(escenario, posicion, direccion, velocidad);
        return aeronave;
    }

    private void crearUnaPosicionAleatoriaYDireccion(int extremoSup, int extremoDer){
    /*PreCondicion: la industria debe estar creada
      PostCondicion: devuelve una posicion que se encuentre en los bordes del escenario*/
        double x, y;
        x = Math.random()*(extremoDer);
        y = Math.random()*(extremoSup);
        switch((int)(Math.random()*4+1)){
            case 1: posicion= new Posicion(1, (int)y);
                    direccion = new Derecha();
                    break;
            case 2: posicion= new Posicion(extremoDer, (int)y);
                    direccion = new Izquierda();
                    break;
            case 3: posicion= new Posicion((int)x, 1);
                    direccion = new Arriba();
                    break;
            default: posicion= new Posicion((int)x, extremoSup);
                    direccion = new Abajo();
                    break;
        }
    }

    private Aeronave crearAeronaveDeTipo1(Escenario escenario, Posicion posicion, Direccion direccion, int velocidad){
    /*PreCondicion: la industria debe estar creada al igual que los elementos que se le pasa por parametro
      PostCondicion: en caso que el avion simple no pueda aterrizar en ninguna pista entonces se devuelve null, en caso
      contrario devuelve un avion simple*/
        Aeronave aeronave = new AvionSimple(posicion, direccion, velocidad);
        if (escenario.enAlgunaPistaSePuedeAterrizar(aeronave)) return aeronave;
        return null;
    }

    private Aeronave crearAeronaveDeTipo2(Escenario escenario, Posicion posicion, Direccion direccion, int velocidad){
    /*PreCondicion: la industria debe estar creada al igual que los elementos que se le pasa por parametro
      PostCondicion: en caso que el avion pesado no pueda aterrizar en ninguna pista entonces se devuelve null, en caso
      contrario devuelve un avion pesado*/
        Aeronave aeronave = new AvionPesado(posicion, direccion, velocidad);
        if (escenario.enAlgunaPistaSePuedeAterrizar(aeronave)) return aeronave;
        return null;
    }

    private Aeronave crearAeronaveDeTipo3(Escenario escenario, Posicion posicion, Direccion direccion, int velocidad){
    /*PreCondicion: la industria debe estar creada al igual que los elementos que se le pasa por parametro
      PostCondicion: en caso que el avion no pueda aterrizar en ninguna pista entonces se devuelve null, en caso
      contrario devuelve un avion computarizado*/
        Aeronave aeronave = new AvionComputarizado(posicion, direccion, velocidad);
        if (!escenario.enAlgunaPistaSePuedeAterrizar(aeronave)) return null;
        ArrayList<Pista> pistas = escenario.obtenerPistas();
        Posicion posEntrada = this.buscarLaEntradaParaUnaAeronave(pistas, aeronave);
        aeronave.agregarTrayectoria(posEntrada);
        return aeronave;
    }

    private Aeronave crearAeronaveDeTipo4(Escenario escenario, Posicion posicion, Direccion direccion, int velocidad){
    /*PreCondicion: la industria debe estar creada al igual que los elementos que se le pasa por parametro
      PostCondicion: en caso que el helicoptero no pueda aterrizar en ninguna pista entonces se devuelve null, en caso
      contrario devuelve un helicoptero*/
        Aeronave aeronave = new Helicoptero(posicion, direccion, velocidad);
        if (escenario.enAlgunaPistaSePuedeAterrizar(aeronave)) return aeronave;
        return null;
    }

    private Posicion buscarLaEntradaParaUnaAeronave(ArrayList<Pista> pistas, Aeronave aeronave){
    /*PreCondicion: la industria debe estar creada al igual que los elementos que se le pasa por parametro y la
      aeronave debe poder aterrizar en alguna pista del escenario
      PostCondicion: devuelve null si el avion no puede aterrizarse en ninguna pista, en caso contrario devuelve
      la posicion de la entrada de la primera pista a la que pueda aterrizar*/
        Posicion pos = null;
        Pista pista;
        boolean seguirBuscando = true;
        Iterator<Pista> iteradorPista = pistas.iterator();
        while (iteradorPista.hasNext() && seguirBuscando){
            pista = iteradorPista.next();
            if (aeronave.puedeAterrizarEn(pista)){
                pos = pista.devolverUnaDeSusEntradas();
                seguirBuscando = false;
            }
        }
        return pos;
    }

    private Aeronave crearAeronave(Escenario escenario, Posicion posicion, Direccion direccion, int velocidad){
    /*PreCondicion: la industria debe haberse creado, el escenario debe contener al menos una pista
      PostCondicion: devuelve una aeronave que pueda aterrizar en el escenario*/
        switch ((int)(Math.random()*4+1)){
            case 1 : return this.crearAeronaveDeTipo1(escenario, posicion, direccion, velocidad);
            case 2 : return this.crearAeronaveDeTipo2(escenario, posicion, direccion, velocidad);
            case 3 : return this.crearAeronaveDeTipo3(escenario, posicion, direccion, velocidad);
            default : return this.crearAeronaveDeTipo4(escenario, posicion, direccion, velocidad);
        }
    }
}
